From 5150e633298359e28c08e3657ec22294984e025c Mon Sep 17 00:00:00 2001 From: "akw27@boulderdash.cl.cam.ac.uk" Date: Fri, 14 Feb 2003 16:43:07 +0000 Subject: [PATCH] bitkeeper revision 1.36 (3e4d1c9bh5tZF-JT9Immw5NWGJ6juw) pre-checkin cleanup --- xen-2.4.16/net/dev.c | 216 +++--------------- xen-2.4.16/net/skbuff.c | 17 +- .../arch/xeno/drivers/network/network.c | 49 +--- xenolinux-2.4.16-sparse/net/core/skbuff.c | 11 +- 4 files changed, 43 insertions(+), 250 deletions(-) diff --git a/xen-2.4.16/net/dev.c b/xen-2.4.16/net/dev.c index b9d9a2c82f..99e0c94fd7 100644 --- a/xen-2.4.16/net/dev.c +++ b/xen-2.4.16/net/dev.c @@ -507,7 +507,13 @@ int dev_queue_xmit(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct Qdisc *q; -if (!(dev->features&NETIF_F_SG)) printk("NIC doesn't do SG!!!\n"); + + if (!(dev->features&NETIF_F_SG)) + { + printk("NIC doesn't do scatter-gather!\n"); + BUG(); + } + if (skb_shinfo(skb)->frag_list && !(dev->features&NETIF_F_FRAGLIST) && skb_linearize(skb, GFP_ATOMIC) != 0) { @@ -679,30 +685,16 @@ void deliver_packet(struct sk_buff *skb, net_vif_t *vif) { net_shadow_ring_t *shadow_ring; rx_shadow_entry_t *rx; - unsigned long *g_pte; //tmp + unsigned long *g_pte; struct pfn_info *g_pfn, *h_pfn; - unsigned int i; //, nvif; + unsigned int i; - /* - * Write the virtual MAC address into the destination field - * of the ethernet packet. Furthermore, do the same for ARP - * reply packets. This is easy because the virtual MAC address - * is always 00-[nn]-00-00-00-00, where the second sixteen bits - * of the MAC are the vif's id. This is to differentiate between - * vifs on guests that have more than one. - * - * In zero copy, the data pointers for the packet have to have been - * mapped in by the caller. - */ - memset(skb->mac.ethernet->h_dest, 0, ETH_ALEN); -// *(unsigned int *)(skb->mac.ethernet->h_dest + 1) = nvif; if ( ntohs(skb->mac.ethernet->h_proto) == ETH_P_ARP ) { memset(skb->nh.raw + 18, 0, ETH_ALEN); -// *(unsigned int *)(skb->nh.raw + 18 + 1) = nvif; } shadow_ring = vif->shadow_ring; @@ -789,14 +781,17 @@ int netif_rx(struct sk_buff *skb) get_fast_time(&skb->stamp); if ( (skb->data - skb->head) != (18 + ETH_HLEN) ) - printk("headroom was %lu!\n", (unsigned long)skb->data - (unsigned long)skb->head); - // BUG(); + BUG(); skb->head = (u8 *)map_domain_mem(((skb->pf - frame_table) << PAGE_SHIFT)); /* remapping this address really screws up all the skb pointers. We need - * to map them all here sufficiently to get the packet demultiplexed. - */ + * to map them all here sufficiently to get the packet demultiplexed. + * + * this remapping happens more than once in the code and is grim. It will + * be fixed in a later update -- drivers should be able to align the packet + * arbitrarily. + */ skb->data = skb->head; skb_reserve(skb,18); // 18 is the 16 from dev_alloc_skb plus 2 for # @@ -805,9 +800,6 @@ int netif_rx(struct sk_buff *skb) skb->data += ETH_HLEN; skb->nh.raw = skb->data; - /* The code is rearranged so that the path is the most - short when CPU is congested, but is still operating. - */ queue = &softnet_data[this_cpu]; netdev_rx_stat[this_cpu].total++; @@ -817,15 +809,9 @@ int netif_rx(struct sk_buff *skb) if ( skb->dst_vif == VIF_UNKNOWN_INTERFACE ) skb->dst_vif = __net_get_target_vif(skb->mac.raw, skb->len, skb->src_vif); -//if (skb->dst_vif == VIF_DROP) -//printk("netif_rx target: %d (sec: %u)\n", skb->dst_vif, skb->security); if ( (vif = sys_vif_list[skb->dst_vif]) == NULL ) - { -//printk("No such vif! (%d).\n", skb->dst_vif); - // the target vif does not exist. goto drop; - } /* This lock-and-walk of the task list isn't really necessary, and is an * artifact of the old code. The vif contains a pointer to the skb list @@ -985,6 +971,16 @@ static inline void handle_diverter(struct sk_buff *skb) } #endif /* CONFIG_NET_DIVERT */ + +/* + * update_shared_ring(void) + * + * This replaces flush_rx_queue as the guest event handler to move packets queued in + * the guest ring up to the guest. Really, the packet is already there, it was page + * flipped in deliver_packet, but this moves the ring descriptor across from the + * shadow ring and increments the pointers. + */ + void update_shared_ring(void) { rx_shadow_entry_t *rx; @@ -1017,156 +1013,6 @@ void update_shared_ring(void) } } -void flush_rx_queue(void) -{ - struct sk_buff *skb; - shared_info_t *s = current->shared_info; - net_ring_t *net_ring; - net_shadow_ring_t *shadow_ring; - unsigned int i, nvif; - rx_shadow_entry_t *rx; - unsigned long *g_pte, tmp; - struct pfn_info *g_pfn, *h_pfn; - - /* I have changed this to batch flush all vifs for a guest - * at once, whenever this is called. Since the guest is about to be - * scheduled and issued an RX interrupt for one nic, it might as well - * receive all pending traffic although it will still only get - * interrupts about rings that pass the event marker. - * - * If this doesn't make sense, _HYP_EVENT_NET_RX can be modified to - * represent individual interrups as _EVENT_NET_RX and the outer for - * loop can be replaced with a translation to the specific NET - * interrupt to serve. --akw - */ - clear_bit(_HYP_EVENT_NET_RX, ¤t->hyp_events); - - for (nvif = 0; nvif < current->num_net_vifs; nvif++) - { - net_ring = current->net_vif_list[nvif]->net_ring; - shadow_ring = current->net_vif_list[nvif]->shadow_ring; - while ( (skb = skb_dequeue(¤t->net_vif_list[nvif]->skb_list)) - != NULL ) - { - //temporary hack to stop processing non-zc skbs. - if (skb->skb_type == SKB_NORMAL) continue; - /* - * Write the virtual MAC address into the destination field - * of the ethernet packet. Furthermore, do the same for ARP - * reply packets. This is easy because the virtual MAC address - * is always 00-00-00-00-00-00. - * - * Actually, the MAC address is now all zeros, except for the - * second sixteen bits, which are the per-host vif id. - * (so eth0 should be 00-00-..., eth1 is 00-01-...) - */ - - if (skb->skb_type == SKB_ZERO_COPY) - { - skb->head = (u8 *)map_domain_mem(((skb->pf - frame_table) << PAGE_SHIFT)); - skb->data = skb->head; - skb_reserve(skb,16); - skb->mac.raw = skb->data; - skb->data += ETH_HLEN; - } - - memset(skb->mac.ethernet->h_dest, 0, ETH_ALEN); - *(unsigned int *)(skb->mac.ethernet->h_dest + 1) = nvif; - if ( ntohs(skb->mac.ethernet->h_proto) == ETH_P_ARP ) - { - memset(skb->nh.raw + 18, 0, ETH_ALEN); - *(unsigned int *)(skb->nh.raw + 18 + 1) = nvif; - } - - if (skb->skb_type == SKB_ZERO_COPY) - { - unmap_domain_mem(skb->head); - } - - i = net_ring->rx_cons; - if ( i != net_ring->rx_prod ) - { - net_ring->rx_ring[i].status = shadow_ring->rx_ring[i].status; - if ( shadow_ring->rx_ring[i].status == RING_STATUS_OK) - { - rx = shadow_ring->rx_ring+i; - if ( (skb->len + ETH_HLEN) < rx->size ) - rx->size = skb->len + ETH_HLEN; - - /* remap the packet again. This is very temporary and will shortly be - * replaced with a page swizzle. - */ - - /*if (skb->skb_type == SKB_ZERO_COPY) - { - skb->head = (u8 *)map_domain_mem(((skb->pf - frame_table) << PAGE_SHIFT)); - skb->data = skb->head; - skb_reserve(skb,16); - skb->mac.raw = skb->data; - skb->data += ETH_HLEN; - } - - copy_to_user((void *)rx->addr, skb->mac.raw, rx->size); - copy_to_user(net_ring->rx_ring+i, rx, sizeof(rx)); - - if (skb->skb_type == SKB_ZERO_COPY) - { - unmap_domain_mem(skb->head); - skb->head = skb->data = skb->tail = (void *)0xdeadbeef; - }*/ - - //presumably I don't need to rewalk the guest page table - //here. - if (skb->skb_type == SKB_ZERO_COPY) - { - // g_pfn is the frame FROM the guest being given up - // h_pfn is the frame FROM the hypervisor, passing up. - - if (rx->flush_count == tlb_flush_count[smp_processor_id()]) - { - flush_tlb_all(); - } - - g_pte = map_domain_mem(rx->addr); - - //g_pfn = frame_table + (rx->addr >> PAGE_SHIFT); - g_pfn = frame_table + (*g_pte >> PAGE_SHIFT); - h_pfn = skb->pf; - - - //tmp = g_pfn->next; g_pfn->next = h_pfn->next; h_pfn->next = tmp; - //tmp = g_pfn->prev; g_pfn->prev = h_pfn->prev; h_pfn->prev = tmp; - tmp = g_pfn->flags; g_pfn->flags = h_pfn->flags; h_pfn->flags = tmp; - - h_pfn->tot_count = 1; - h_pfn->type_count = g_pfn->type_count; - g_pfn->tot_count = g_pfn->type_count = 0; - - h_pfn->flags = current->domain | PGT_l1_page_table; - g_pfn->flags = PGT_l1_page_table; - - - *g_pte = (*g_pte & ~PAGE_MASK) | (((h_pfn - frame_table) << PAGE_SHIFT) & PAGE_MASK); - - *g_pte |= _PAGE_PRESENT; - unmap_domain_mem(g_pte); - - skb->pf = g_pfn; // return the guest pfn to be put on the free list - } else { - BUG(); //got a non-zero copy skb. which is not good. - } - - } - net_ring->rx_cons = (i+1) & (RX_RING_SIZE-1); - if ( net_ring->rx_cons == net_ring->rx_event ) - set_bit(_EVENT_NET_RX, &s->events); - } - kfree_skb(skb); - } - } -} - - /* * Map an interface index to its name (SIOCGIFNAME) */ @@ -2180,16 +2026,6 @@ void tx_skb_release(struct sk_buff *skb) */ #define PKT_PROT_LEN (ETH_HLEN + 8) -void print_range2(u8 *start, unsigned int len) -{ - int i=0; - while (i++ < len) - { - printk("%x:",start[i]); - } - printk("\n"); -} - long do_net_update(void) { shared_info_t *shared = current->shared_info; diff --git a/xen-2.4.16/net/skbuff.c b/xen-2.4.16/net/skbuff.c index 2df98d791e..ec9b59bdbd 100644 --- a/xen-2.4.16/net/skbuff.c +++ b/xen-2.4.16/net/skbuff.c @@ -150,8 +150,6 @@ static __inline__ void skb_head_to_pool(struct sk_buff *skb) kmem_cache_free(skbuff_head_cache, skb); } -//static unsigned long skbpagesout=0, skbpagesin=0; - static inline u8 *alloc_skb_data_page(struct sk_buff *skb) { struct list_head *list_ptr; @@ -166,13 +164,11 @@ static inline u8 *alloc_skb_data_page(struct sk_buff *skb) pf = list_entry(list_ptr, struct pfn_info, list); pf->flags = 0; // owned by dom0 list_del(&pf->list); - //pf->next = pf->prev = (pf - frame_table); free_pfns--; spin_unlock_irqrestore(&free_list_lock, flags); skb->pf = pf; -//if (skbpagesout++ % 100 == 0) printk("XEN-: skb allocs: %lu\n", skbpagesout); return (u8 *)((pf - frame_table) << PAGE_SHIFT); } @@ -190,7 +186,6 @@ static inline void dealloc_skb_data_page(struct sk_buff *skb) spin_unlock_irqrestore(&free_list_lock, flags); -//if (skbpagesin++ % 100 == 0) printk("XEN-: skb allocs: %lu\n", skbpagesin); } struct sk_buff *alloc_zc_skb(unsigned int size,int gfp_mask) @@ -406,10 +401,16 @@ static void skb_release_data(struct sk_buff *skb) if (skb_shinfo(skb)->frag_list) skb_drop_fraglist(skb); - if (skb->skb_type == SKB_NORMAL) { + if (skb->skb_type == SKB_NORMAL) + { kfree(skb->head); - } else if (skb->skb_type == SKB_ZERO_COPY) { dealloc_skb_data_page(skb); - } else { + } + else if (skb->skb_type == SKB_ZERO_COPY) + { + dealloc_skb_data_page(skb); + } + else + { BUG(); //skb_release_data called with unknown skb type! } } diff --git a/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c b/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c index c553b818fc..5795d889e8 100644 --- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c +++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c @@ -186,35 +186,7 @@ inline unsigned long get_ppte(unsigned long addr) return ppte; } -/* -static void validate_free_list(void) -{ - unsigned long addr, ppfn, mpfn, mpfn2, flags; - struct list_head *i; - struct net_page_info *np; - - printk(KERN_ALERT "Walking free pages:\n"); - - spin_lock_irqsave(&net_page_list_lock, flags); - - list_for_each(i, &net_page_list) - { - np = list_entry(i, struct net_page_info, list); - addr = np->virt_addr; - ppfn = virt_to_phys(addr) >> PAGE_SHIFT; - mpfn = get_ppte(addr); - mpfn2 = phys_to_machine_mapping[ppfn]; - - mpfn = (*(unsigned long *)phys_to_virt(machine_to_phys(mpfn))) >> PAGE_SHIFT; - if (mpfn != mpfn2) printk(KERN_ALERT "mpfn %lu != %lu\n", mpfn, mpfn2); - - if (machine_to_phys_mapping[mpfn] != ppfn) printk(KERN_ALERT "ppfn %lu != %lu\n", machine_to_phys_mapping[mpfn], ppfn); - } - spin_unlock_irqrestore(&net_page_list_lock, flags); - -} -*/ static void network_alloc_rx_buffers(struct net_device *dev) { unsigned int i; @@ -232,7 +204,6 @@ static void network_alloc_rx_buffers(struct net_device *dev) np->rx_skb_ring[i] = skb; np->net_ring->rx_ring[i].addr = get_ppte(skb->head); np->net_ring->rx_ring[i].size = RX_BUF_SIZE - 16; /* arbitrary */ -//printk(KERN_ALERT "[%p]\n", phys_to_machine(virt_to_phys(skb->page_ptr))); } np->net_ring->rx_prod = i; @@ -256,15 +227,6 @@ static void network_free_rx_buffers(struct net_device *dev) } } -void print_range(u8 *start, unsigned int len) -{ - int i = 0; - - while (i++ < len) - printk("%x:", start[i]); - printk("\n"); -} - static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned int i; @@ -276,9 +238,6 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); return -ENOBUFS; } -//print_range(skb->data, ETH_HLEN + 8); -//print_range(skb->data + ETH_HLEN + 8, 20); -//printk("skb->len is %u in guestOS (expected fraglen: %u).\n", skb->len, skb->len - (ETH_HLEN + 8)); i = np->net_ring->tx_prod; if ( (((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= PAGE_SIZE ) @@ -331,8 +290,6 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs) struct net_private *np = dev->priv; struct sk_buff *skb; - /*if (net_countx++ % 100 == 0) validate_free_list();*/ - again: for ( i = np->rx_idx; i != np->net_ring->rx_cons; i = RX_RING_INC(i) ) { @@ -344,8 +301,6 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs) } skb = np->rx_skb_ring[i]; -//printk(KERN_ALERT "[%u]: ptmm[%lx] old:(%lx) new:(%lx)\n", i , virt_to_phys(skb->head) >> PAGE_SHIFT, phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT], (*(unsigned long *)phys_to_virt(machine_to_phys(np->net_ring->rx_ring[i].addr))) >> PAGE_SHIFT); - phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT] = (*(unsigned long *)phys_to_virt( machine_to_phys(np->net_ring->rx_ring[i].addr)) @@ -354,8 +309,8 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs) skb_put(skb, np->net_ring->rx_ring[i].size); skb->protocol = eth_type_trans(skb, dev); - /* Set up shinfo -- from alloc_skb */ - /* This was particularily nasty: the shared info is hidden at the back of the data area + /* Set up shinfo -- from alloc_skb + * This was particularily nasty: the shared info is hidden at the back of the data area * (presumably so it can be shared), but on page flip it gets very spunked. */ diff --git a/xenolinux-2.4.16-sparse/net/core/skbuff.c b/xenolinux-2.4.16-sparse/net/core/skbuff.c index 45332f1ffd..f900d88768 100644 --- a/xenolinux-2.4.16-sparse/net/core/skbuff.c +++ b/xenolinux-2.4.16-sparse/net/core/skbuff.c @@ -433,6 +433,7 @@ static void skb_release_data(struct sk_buff *skb) atomic_dec_and_test(&(skb_shinfo(skb)->dataref))) { if (skb_shinfo(skb)->nr_frags) { int i; +printk("there were %u frags!\n", skb_shinfo(skb)->nr_frags); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { put_page(skb_shinfo(skb)->frags[i].page); @@ -442,14 +443,14 @@ static void skb_release_data(struct sk_buff *skb) if (skb_shinfo(skb)->frag_list) skb_drop_fraglist(skb); - if (skb->skb_type == SKB_NORMAL) - { + //if (skb->skb_type == SKB_NORMAL) + //{ kfree(skb->head); - } else {// SKB_ZERO_COPY + //} else {// SKB_ZERO_COPY //free_net_page(skb->net_page); //printk(KERN_ALERT "<%p>\n", phys_to_machine(virt_to_phys(skb->head))); - free_page((void *)skb->head); - } + // free_page((void *)skb->head); + //} } } -- 2.30.2